package com.xiguaji.tiktok.task.monitor.aop;

import cn.hutool.core.date.DateUtil;
import com.xiguaji.boot.toolkit.DateTimeUtils;
import com.xiguaji.boot.toolkit.JsonUtil;
import com.xiguaji.tiktok.task.monitor.LogUtil;
import com.xiguaji.tiktok.task.monitor.Monitor;
import com.xxl.job.core.handler.annotation.XxlJob;
import com.xxl.job.core.log.XxlJobLogger;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import java.time.Instant;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Map;

@Slf4j
@Aspect
@Component
public class TaskLog {

    @Autowired
    RedisTemplate<String,String> redisTemplate;


    // @Pointcut(value = "execution(* com.xiguaji..*.*Task.*(..))")
    @Pointcut(value = "@annotation(com.xiguaji.tiktok.task.monitor.aop.RedisMonitor)")
    public void Pointcut(){
    }


    public void writeLog(ProceedingJoinPoint proceedingJoinPoint)   {
        log.info("into aop");
        Object[] args = proceedingJoinPoint.getArgs();

        if(args[0] != null && !StringUtils.isEmpty(args[0].toString())){
            try{
                Map argsMap = JsonUtil.jsonParse(Map.class,args[0].toString());

                if(null != argsMap.get("id")){
                    LocalDateTime start = LocalDateTime.now();
                    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

                    Monitor monitor = new Monitor();
                    monitor.setLogId(LogUtil.getLogId());
                    monitor.setJobId(argsMap.get("id").toString());
                    monitor.setStartTime(start.format(formatter));

                    // 任务超时设置，默认10分钟
                    long estimateTime = start.atZone(ZoneId.systemDefault()).toEpochSecond();
                    if(null != argsMap.get("estimateTime")){
                        estimateTime += Long.parseLong(argsMap.get("estimateTime").toString());
                    }else{
                        estimateTime +=600;
                    }

                    monitor.setEstimateTime(LocalDateTime.ofInstant(Instant.ofEpochSecond(estimateTime), ZoneId.systemDefault()).format(formatter));
                    LogUtil.contextHolder.set("job_"+monitor.getJobId() + "_" + monitor.getLogId()+"_"+ start.format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss")));
                    redisTemplate.opsForValue().set(LogUtil.contextHolder.get(), JsonUtil.parseJson(monitor));
                }
            }catch (Exception e){
                log.error("TaskLog aop error !",e);
                XxlJobLogger.log("TaskLog aop error !",e);
            }
        }

    }
    @Around(value = "Pointcut()")
    public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        try {
            before(proceedingJoinPoint);
            Object result = proceedingJoinPoint.proceed();
            end();
            return result;
        } catch (Exception e ) {
            log.error("TaskLog aop error !", e);
            XxlJobLogger.log("TaskLog aop error !", e);
            throw e;
        } finally {
            LogUtil.delLogData();
            LogUtil.contextHolder.remove();
        }
    }
    private void before(ProceedingJoinPoint proceedingJoinPoint){
        writeLog(proceedingJoinPoint);
    }
    private void end(){

    }
}
